/**
  * @file 		TDKMode.c
  * @brief		基于TDKCH202的接近感应模组的驱动文件
  *
  * @copyright  Copyright (c) 2017~2020 ShenZhen Dxtc Technology Co., Ltd. 
  * All rights reserved.
  *
  * @version	V0.00.002
  * @author		zhanggang
  * @date 		2022-08-26
  * 
  * @note		这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  * 
  * @par 修改日志:
  * <1> 2022/08/26 V0.00.001 zhanggang 创建初始版本
  * <2> 2022/10/31 V0.00.002 Shenjiwei 优化代码，增加注释
  *******************************************************************/
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "TDKMode.h"
#include "device.h"
#include "component.h"
#include "osal.h"

#define TDKMODE_LOG(format, ...) OSAL_LOG(C_BLUE format C_NONE, ##__VA_ARGS__)
#define __TDKMODE_LOG(format, ...) __OSAL_LOG(C_BLUE format C_NONE, ##__VA_ARGS__)

/** @brief 模组从机地址 */
#define IIC_ADDR_TDKMODE 0x50

/** @brief 模组电源驱动、唤醒、中断等引脚定义 */
#define VHW_PIN_TDKMODEL_POWER vPIN_C15
#define VHW_PIN_TDKMODEL_EN vPIN_C16
#define VHW_IRQ_TDKMODEL vPIN_I12

/** @brief 任务事件类型定义 */
#define EVENT_SET_PARA   (0X00000001)
#define EVENT_GET_WANDER (0X00000002)

tdkmodel_config_t  tdkmodel_config_data_t;      ///< TDK模组参数结构，主要用于存放读出的参数
tdkmodel_config_t  tdkmodel_config_Wirtedata_t; ///< TDK模组参数结构，主要用于存放写入的参数

#define TDK_TIMEOUT_TIME                    60*5      ///< 5分钟，每次触发徘徊报警后下一次开始检测的间隔
static uint32_t tdk_timeout_timestamp = TDK_TIMEOUT_TIME;  ///< 超时时间戳
static uint8_t flag = 1;   ///< 标记TDK模组唤醒标志，单条设置为1，多条设置为0；

/** @brief 模组运行状态（枚举） */
typedef enum {
  DEVICE_POWER_OFF,    //< 电源关
  DEVICE_NO_FIRMWARE,  //< 模组无固件
  DEVICE_READY,        //< 模组已就绪
  DEVICE_ERROR,        //< 模组出错
  DEVICE_POWER_ON,     //< 电源开
} Dsensor_Status_enum_t;

/** @brief 传感器类型 */
typedef enum {
  DSENSOR_UNKNOWN,  //< 无模组
  DSENSOR_AMS,      //< AMS(TMF8801)模组
  DSENSOR_ND,       //< ND03B传感器
  DSENSOR_TDKMODE   //< TDK传感器
} SensorType_enum_t;
/** @brief TDK模组参数设置 */
typedef struct 
{
    uint8_t init_flag;         //< 初始化标志

    uint8_t near_enable;       //< 接近感应开关使能
    uint8_t threshold_near;    //< 接近感应灵敏度

    uint16_t distance_wander;   //< 徘徊距离
    uint8_t wander_enable;     //< 徘徊开关使能
    uint8_t wander_state;      //< 徘徊传感器状态 1：允许触发 0：不允许触发
    uint8_t  threshold_wander;  //< 徘徊灵敏度阈值
    uint32_t wander_time;      //< 徘徊时间
}tdkwander_info_t;             
tdkwander_info_t tdkwander_info = {0}; ///< 定义TDK模组参数设置结构（用于模组设置或者读取时保存）
__EFRAM static uint8_t demo_mode = 0;  ///< 上电或重启默认状态
__EFRAM static uint8_t err_flag = 0xff;

/**
  * @brief  故障处理
  * @note   IIC故障通知，若IIC通信失败则接近和徘徊等参数设置必定失败，
  * 故本组件只挑选部分设置判断错误码，目前有徘徊距离、徘徊时间、接近阈值
  * 以及模组的检测时间设置等做了故障码判断。
  * 
  * @param  err：是否故障
  * @return void
  */
static void err_process(uint8_t err)
{
    if (err != err_flag)
    {
        err_flag = err;
        TDKMODE_LOG("TDK err code flag: %d \r\n",err_flag);
        OSAL_MessagePublishErrorCode(ERRCODE_TYPE_DSENSOR, err_flag);
    }
}

 /**
   *@brief       TDK模组多条设置，唤醒引脚使能设置
   *
   * 
   *@return      NULL
   */
static void TDKDevice_Enable()
{
    flag = 0;
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);
    Device_DelayMs(2);
}

 /**
   *@brief       TDK模组多条设置，唤醒引脚禁能设置
   *
   * 
   *@return      NULL
   */
static void TDKDevice_DisEnable()
{
    flag = 1;
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
}

 /**
   *@brief       传感器IIC写函数
   *
   *@param[in]   regaddr:写数据地址
   *@param[in]   regaddr:数据内容地址
   *@param[in]   regaddr:数据长度
   * 
   *@return      SUCCESS：成功   ERROR：失败/出错
   */
static uint32_t tdkmodel_i2c_write(uint8_t regaddr, uint8_t *buf, uint32_t len)
{
    unsigned char buffer[130] = {regaddr};

	memcpy(&buffer[1], buf, len);
	return (Device_Write(VHW_IIC_TDKMODE, buffer, len + 1, IIC_ADDR_TDKMODE) == 0) ? 0 : 1;
}

/**
  *@brief       传感器IIC读函数
  *
  *@param[in]   regaddr:读数据地址
  *@param[in]   regaddr:数据内容地址
  *@param[in]   regaddr:数据长度 
  *
  *@return      SUCCESS：成功   ERROR：失败/出错
  */
static uint32_t tdkmodel_i2c_read(uint8_t regaddr, uint8_t *buf, uint32_t len)
{
    if (Device_Write(VHW_IIC_TDKMODE, &regaddr, 1, IIC_ADDR_TDKMODE) == 0)
	{
		return (Device_Read(VHW_IIC_TDKMODE, buf, len, IIC_ADDR_TDKMODE) == 0) ? 0 : 1;
	}
	return 1;
}

/**
  *@brief       读传感器读寄存器测试数据
  *@details     读传感器的实测距离以及强度阈值
  * 
  *@return      NULL
  */
static void tdkmodel_read_testdata(uint16_t *ps, uint16_t *cfi)
{
    uint8_t state;
    uint8_t reg_buff[2];

    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);        //< 唤醒脚拉高
    Device_DelayMs(2);
    tdkmodel_i2c_read(REGADDR_TRIGGER_FLAG,&state,1);   //< 传感器触发标志
    tdkmodel_i2c_read(0x15,reg_buff,2);          //< 读接近感应触发距离
    *ps = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x1D,reg_buff,2);          //< 读近感应触发强度
    *cfi = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);        //< 唤醒脚拉高
    TDKMODE_LOG("trigger_flag: %d, ps: %d mm, cfi: %d\r\n",state, *ps, *cfi);

}

/**
  *@brief       设置模组功能总开关
  * 
  *@param[in]   modul_flag: 开关标志，0：传感器功能关闭，模组睡眠；1：传感器功能打开，模组工作
  * 
  *@return      NULL
  */
static ErrorStatus tdkmodel_set_onoff(uint8_t modul_flag)
{
      uint8_t state;

      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}  //< 唤醒脚拉高
      tdkmodel_i2c_write(REGADDR_ON_OFF_STATE,&modul_flag,1); //< 设置检测最大距离
      tdkmodel_i2c_read(REGADDR_ON_OFF_STATE,&state,1);  //< 读取检测最大距离
      if(flag ==1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低
   
      if(state ==  modul_flag) //< 判断设置的（最大检测）距离与读出的距离是否一致
      {
       TDKMODE_LOG("set module on_off SUCCESS,modul_flag=%d", modul_flag); 
       return SUCCESS;     
      }
      else 
      {
        TDKMODE_LOG("set module on_off ERROR");
        return ERROR;
      }

}

/**
  * @brief  hex转字符
  *         
  * @note   
  * @param  len: hex数组长度
  * @param  inchar：输入hex数组首地址
  * @param  outtxt：转换输出成字符数组首地址
  */
static void Hex2Str (uint8_t *inchar,  int len, uint8_t *outtxt)
{
        unsigned char hbit,lbit;
        unsigned int i;
  	for(i=0;i<len;i++)
	{
		hbit = (*(inchar+i)&0xf0)>>4;
		lbit = *(inchar+i)&0x0f;
		if (hbit>9) outtxt[2*i]='A'+hbit-10;
		else outtxt[2*i]='0'+hbit;
		if (lbit>9) outtxt[2*i+1]='A'+lbit-10;
		else    outtxt[2*i+1]='0'+lbit;
	 }
}

/**
  *@brief       读传感器版本
  * 
  *@return      0:无效
  */
static uint32_t tdkmodel_read_softversion(uint8_t *pData)
{
    uint8_t reg_buff[3];

    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1); //< 唤醒脚拉高
    Device_DelayMs(2);

    tdkmodel_i2c_read(0x01,reg_buff,2);          //< 读模组版本
    Hex2Str(reg_buff,2,pData);
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);  //< 唤醒脚拉低，模组待机

    return 0;
}

/**
  *@brief       传感器读寄存器所有(全部)数据
  * 
  *@return      0:无效
  */
static uint32_t tdkmodel_read_regdata(void)
{
    uint8_t reg_buff[50];
    uint8_t i;
     Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1); //< 唤醒脚拉高
     Device_DelayMs(2);
    tdkmodel_i2c_read(0x01,reg_buff,2);          //< 读模组版本
    tdkmodel_config_data_t.soft_version = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x03,reg_buff,2);          //< 读徘徊检测最大距离
    tdkmodel_config_data_t.max_distance_wander = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x05,reg_buff,2);          //< 读徘徊检测周期
    tdkmodel_config_data_t.cycle_detection_wander = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x07,reg_buff,2);          //< 读徘徊检测触发阈值
    tdkmodel_config_data_t.trigger_threshold_wander = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x09,reg_buff,2);          //< 读徘徊检测停留时间
    tdkmodel_config_data_t.time_stay_wander = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x0B,reg_buff,2);          //< 读接近感应有效距离
    tdkmodel_config_data_t.max_distance_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x0D,reg_buff,2);          //< 读接近感应检测停留时间
    tdkmodel_config_data_t.time_stay_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x0F,reg_buff,2);          //< 读接近感应检测周期
    tdkmodel_config_data_t.cycle_detection_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x11,reg_buff,2);          //< 读接近感应触发阈值
    tdkmodel_config_data_t.trigger_threshold_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x13,reg_buff,2);          //< 读徘徊检测触发距离
    tdkmodel_config_data_t.realtrigger_distance_wander = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x15,reg_buff,2);          //< 读接近感应触发距离
    tdkmodel_config_data_t.realtrigger_distance_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x18,reg_buff,1);          //< 读模组工作状态
    tdkmodel_config_data_t.work_state =  reg_buff[0];
    tdkmodel_i2c_read(0x19,reg_buff,1);          //< 读徘徊检测触发次数
    tdkmodel_config_data_t.trigger_frequency_wander =  reg_buff[0];
    tdkmodel_i2c_read(0x1A,reg_buff,1);          //< 读接近感应触发次数
    tdkmodel_config_data_t.trigger_frequency_near =  reg_buff[0];
    tdkmodel_i2c_read(0x1B,reg_buff,2);          //< 读徘徊检测触发强度
    tdkmodel_config_data_t.strength_trigger_threshold_wander =  ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    tdkmodel_i2c_read(0x1D,reg_buff,2);          //< 读近感应触发强度
    tdkmodel_config_data_t.strength_trigger_threshold_near = ((uint16_t)reg_buff[0])<<8|reg_buff[1];
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);  //< 唤醒脚拉低，模组待机
    
    TDKMODE_LOG("max_distance_wander=%dmm",tdkmodel_config_data_t.max_distance_wander);
    TDKMODE_LOG("cycle_detection_wander=%dms",tdkmodel_config_data_t.cycle_detection_wander);
    TDKMODE_LOG("time_stay_wander=%dms",tdkmodel_config_data_t.time_stay_wander);
    TDKMODE_LOG("max_distance_near=%dmm",tdkmodel_config_data_t.max_distance_near);
    TDKMODE_LOG("cycle_detection_near=%dms",tdkmodel_config_data_t.cycle_detection_near);
    TDKMODE_LOG("realtrigger_distance_wander=%dmm",tdkmodel_config_data_t.realtrigger_distance_wander);
    TDKMODE_LOG("realtrigger_distance_near=%dmm",tdkmodel_config_data_t.realtrigger_distance_near);
    TDKMODE_LOG("strength_trigger_threshold_wander=%d",tdkmodel_config_data_t.strength_trigger_threshold_wander);
    TDKMODE_LOG("strength_trigger_threshold_near=%d",tdkmodel_config_data_t.strength_trigger_threshold_near);
    TDKMODE_LOG("work_state=%x",tdkmodel_config_data_t.work_state);
  
    return 0;
}
static DsensorMsg_t dsensor_msg;

/**
  *@brief       读传感器触发标志
  *@details     包括徘徊触发和接近感应触发
  * 
  *@return      SUCCESS：触发   ERROR：未触发
  */
static uint32_t tdkmodel_read_triggerflag(void)
{
    uint8_t reg_buff[5];
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);        //< 唤醒脚拉高
    Device_DelayMs(2);
    tdkmodel_i2c_read(REGADDR_TRIGGER_FLAG,reg_buff,1);//< 传感器触发标志
    tdkmodel_config_data_t.trigger_flag = reg_buff[0];
    tdkmodel_i2c_read(REGADDR_WORK_STATE,reg_buff,1);  //< 模组工作状态
    tdkmodel_config_data_t.work_state =  reg_buff[0];
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);       //< 唤醒脚拉低
    if(tdkmodel_config_data_t.trigger_flag !=0 && tdkmodel_config_data_t.trigger_flag != 0xff)
    {
       return SUCCESS;
    }
    return ERROR;
}

/**
  *@brief       设置模组接近感应距离
  * 
  *@param[in]   max_distance_mm: 设置的最大感应距离的值
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_distance_near(uint16_t max_distance_mm)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_max_distance_mm = 0;
   if(max_distance_mm <= 1200) //< 感应距离不能大于1.2M
   {
      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}  //< 唤醒脚拉高
      tdkmodel_config_Wirtedata_t.max_distance_near = max_distance_mm;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.max_distance_near>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.max_distance_near&0xff);
      tdkmodel_i2c_write(REGADDR_MAX_DISTANCE_NEAR_H,w_reg_buff,2); //< 设置检测最大距离
      
      tdkmodel_i2c_read(REGADDR_MAX_DISTANCE_NEAR_H,r_reg_buff,2);  //< 读取检测最大距离
      if(flag ==1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低
   
      r_max_distance_mm = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      if(r_max_distance_mm ==  tdkmodel_config_Wirtedata_t.max_distance_near) //< 判断设置的（最大检测）距离与读出的距离是否一致
      {
       tdkmodel_config_data_t.max_distance_near = r_max_distance_mm;
       TDKMODE_LOG("set distance_near SUCCESS");
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set distance_near ERROR");
        return ERROR;  
      }
   }
   else
   {
      TDKMODE_LOG("set distance_near ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组最大徘徊距离
  * 
  *@param[in]   max_distance_mm: 设置的最大徘徊距离的值
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_distance_wander(uint16_t max_distance_mm)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_max_distance_mm = 0;
   if(max_distance_mm <= 3000) //< 徘徊距离不能超过3m
   {
     if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}//< 唤醒脚拉高，唤醒模组
      tdkmodel_config_Wirtedata_t.max_distance_wander = max_distance_mm;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.max_distance_wander>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.max_distance_wander&0xff);
      tdkmodel_i2c_write(REGADDR_MAX_DISTANCE_WANDER_H,w_reg_buff,2); //< 设置徘徊检测最大距离
      
      tdkmodel_i2c_read(REGADDR_MAX_DISTANCE_WANDER_H,r_reg_buff,2);  //< 读取徘徊检测最大距离
      r_max_distance_mm = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低，模组进入待机
   
      if(r_max_distance_mm ==  tdkmodel_config_Wirtedata_t.max_distance_wander)//< 判断设置的（最大徘徊）距离与读出的距离是否一致
      {
       tdkmodel_config_data_t.max_distance_wander = r_max_distance_mm;
       err_process(0);
       TDKMODE_LOG("set distance_wander SUCCESS");
       return SUCCESS;
       
      }else 
      {
        err_process(1);
        TDKMODE_LOG("set distance_wander ERROR");
        return ERROR;  
      }
   }
   else
   {
      err_process(1);
      TDKMODE_LOG("set distance_wander ERROR");
      return ERROR;
   }

}

/**
  *@brief       徘徊功能使能设置
  * 
  *@param[in]   wander_switch:使能，0：关闭，1：打开
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_swich_wander(uint8_t wander_switch)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint8_t r_work_state = 0;
   uint8_t w_work_state = 0;
  
  if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}        //< 唤醒脚拉高，唤醒模组
  tdkmodel_i2c_read(REGADDR_WORK_STATE,r_reg_buff,1);//< 读取模组工作状态
  tdkmodel_config_data_t.work_state =  r_reg_buff[0];
  w_work_state = tdkmodel_config_data_t.work_state;
   if(wander_switch == 0)
    {
        w_work_state &= 0xFE;//最低位置0                          
    }else if(wander_switch == 1)
    {
        w_work_state |= 0x01;//最低位置1
    }
      tdkmodel_config_Wirtedata_t.work_state = w_work_state;
      w_reg_buff[0] = tdkmodel_config_Wirtedata_t.work_state;
      tdkmodel_i2c_write(REGADDR_WORK_STATE,w_reg_buff,1); //< 将设置的状态写入模组
      tdkmodel_i2c_read(REGADDR_WORK_STATE,r_reg_buff,1);  //< 读取最新的状态值
      r_work_state = r_reg_buff[0];
      if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低，模组待机
      if(r_work_state ==  w_work_state)  //< 写入和读取的值进行对比，如果一致说明设置成功
      {
       tdkmodel_config_data_t.work_state = r_work_state;
       TDKMODE_LOG("set work_state SUCCESS");
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set work_state  ERROR");
        return ERROR;  
      }
   
}

/**
  *@brief       徘徊功能使能设置
  *@details     该函数与set_tdkmodel_swich_wander()的区别是：将模组状态保存到锁端NV中
  * 
  *@param[in]   wander_switch:使能，0：关闭，1：打开
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t Pir_Switch(uint8_t wander_switch)
{
    if(wander_switch == 0 && tdkwander_info.wander_enable != 0)
    {
        tdkwander_info.wander_enable = 0;
        OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//写入配置
        return set_tdkmodel_swich_wander(0);
    }
    else if(wander_switch == 1 && tdkwander_info.wander_enable != 1)
    {
        tdk_timeout_timestamp = 0;
        tdkwander_info.wander_enable = 1;
        OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//写入配置
        return set_tdkmodel_swich_wander(1);
    }
    else
    {
        TDKMODE_LOG("TDK power on fail\r\n");
        return ERROR;
    }
}

/**
  *@brief       设置模组接近感应功能使能开关
  * 
  *@param[in]   near_switch:（接近感应功能）使能，0：关闭，1：打开
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_swich_near(FunctionalState near_switch)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint8_t r_work_state = 0;
   uint8_t w_work_state = 0;
    if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}       //< 唤醒脚拉高，模组唤醒
    tdkmodel_i2c_read(REGADDR_WORK_STATE,r_reg_buff,1);//< 读取模组工作状态
    tdkmodel_config_data_t.work_state =  r_reg_buff[0];
    w_work_state = tdkmodel_config_data_t.work_state;

    if(near_switch == DISABLE)
    {
        w_work_state &= 0xFD;//bit1置0    
    }else if(near_switch == ENABLE)
    {
        w_work_state |= 0x02;//bit1置1
    }
      tdkmodel_config_Wirtedata_t.work_state = w_work_state;
      w_reg_buff[0] = tdkmodel_config_Wirtedata_t.work_state;
      tdkmodel_i2c_write(REGADDR_WORK_STATE,w_reg_buff,1); //< 将设置的状态写入模组
      tdkmodel_i2c_read(REGADDR_WORK_STATE,r_reg_buff,1);  //< 读取最新的状态值
      r_work_state = r_reg_buff[0];
      if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低，模组待机
    
      if(r_work_state ==  w_work_state) //< 写入和读取的值进行对比，如果一致说明设置成功
      {
       tdkmodel_config_data_t.work_state = r_work_state;
       TDKMODE_LOG("set work_state SUCCESS,work_state:%d",w_work_state);
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set work_state  ERROR");
        return ERROR;  
      }
   
}

/**
  *@brief       接近感应功能使能设置
  *@details     该函数与set_tdkmodel_swich_near()的区别是：将模组状态保存到锁端NV中
  * 
  *@param[in]   wander_switch:使能，0：关闭，1：打开
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static ErrorStatus dsensor_power_ctrl(FunctionalState ctrl)
{
    if(ctrl == DISABLE && tdkwander_info.near_enable != DISABLE)
    {
        tdkwander_info.near_enable = DISABLE;
        OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//保存参数
        return set_tdkmodel_swich_near(DISABLE);
    }
    else
    {
        if(tdkwander_info.threshold_near == DSENSOR_SENS_OFF)
		{
			TDKMODE_LOG("TDK power on fail\r\n");
            return ERROR;
		}
		else if(tdkwander_info.near_enable == DISABLE && ctrl == ENABLE)
		{
            tdkwander_info.near_enable = ENABLE;
            OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//保存参数
			return set_tdkmodel_swich_near(ENABLE);
		}
        else
        {
            return ERROR;
        }
    }
}

/**
  *@brief       设置模组徘徊触发阈值
  * 
  *@param[in]   threshold_wander:阈值（等级），不能大于2
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_threshold_wander(uint8_t threshold_wander)
{
   uint8_t w_reg_buff[3] = {0};
   uint8_t r_reg_buff[3] = {0};
   uint16_t r_threshold_wander = 0;
   if(threshold_wander <= 2)
   {
     if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);} //< 唤醒脚拉高，模组唤醒
      tdkmodel_config_Wirtedata_t.strength_trigger_threshold_wander = threshold_wander;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.strength_trigger_threshold_wander>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.strength_trigger_threshold_wander&0xff);
      tdkmodel_i2c_write(REGADDR_TRIGGER_THRESHOLD_WANDER_H,w_reg_buff,2);//< 设置徘徊触发阈值
      
      tdkmodel_i2c_read(REGADDR_TRIGGER_THRESHOLD_WANDER_H,r_reg_buff,2);//< 读取最新徘徊触发阈值
       r_threshold_wander = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
       if(flag == 1)Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低，模组待机
 
      if(r_threshold_wander ==  tdkmodel_config_Wirtedata_t.strength_trigger_threshold_wander) //< 读写数值对比，确认设置成功
      {
       tdkmodel_config_data_t.strength_trigger_threshold_wander = r_threshold_wander;
       TDKMODE_LOG("set threshold_wander SUCCESS");
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set threshold_wander ERROR");
        return ERROR;  
      }
   }
   else
   {
      TDKMODE_LOG("set threshold_wander ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组接近感应触发阈值
  * 
  *@param[in]   threshold_near:阈值，该值不能大于1W
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_threshold_near(uint16_t threshold_near)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_threshold_near = 0;
   if(threshold_near <= 10000)
   {
     if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}
      tdkmodel_config_Wirtedata_t.strength_trigger_threshold_near = threshold_near;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.strength_trigger_threshold_near>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.strength_trigger_threshold_near&0xff);
      tdkmodel_i2c_write(REGADDR_STRENGTH_TRIGGER_THRESHOLD_NEAR_H,w_reg_buff,2);//< 设置接近感应触发阈值
      
      tdkmodel_i2c_read(REGADDR_STRENGTH_TRIGGER_THRESHOLD_NEAR_H,r_reg_buff,2); //< 读取最新接近感应触发阈值
      r_threshold_near = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
       if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
     
      if(r_threshold_near ==  tdkmodel_config_Wirtedata_t.strength_trigger_threshold_near)  //< 读写数值对比，确认设置成功
      {
       tdkmodel_config_data_t.strength_trigger_threshold_near = r_threshold_near;
       err_process(0);
       TDKMODE_LOG("set threshold_near SUCCESS");
       return SUCCESS;
       
      }else 
      {
        err_process(1);
        TDKMODE_LOG("set threshold_near ERROR");
        return ERROR;  
      }
   }
   else
   {
      err_process(1);
      TDKMODE_LOG("set threshold_near ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组徘徊检测时间
  * 
  *@param[in]   wander_time_ms:徘徊检测时间，该值不能大于60S
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_stay_time_wander(uint16_t wander_time_ms)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_wander_time_ms = 0;
   if(wander_time_ms <= 60000)
   {
      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}
      tdkmodel_config_Wirtedata_t.time_stay_wander = wander_time_ms;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.time_stay_wander>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.time_stay_wander&0xff);
      tdkmodel_i2c_write(REGADDR_TIME_STAY_WANDER_H,w_reg_buff,2); //< 设置徘徊检测时间
      
      tdkmodel_i2c_read(REGADDR_TIME_STAY_WANDER_H,r_reg_buff,2); //< 读取模组的徘徊检测时间
       if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
    
      r_wander_time_ms = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      if(r_wander_time_ms ==  tdkmodel_config_Wirtedata_t.time_stay_wander)  //< 读写数值对比，确认设置成功
      {
       tdkmodel_config_data_t.time_stay_wander = r_wander_time_ms;
       err_process(0);
       TDKMODE_LOG("set time_wander SUCCESS");
       return SUCCESS;
       
      }else 
      {
        err_process(1);
        TDKMODE_LOG("set time_wander ERROR");
        return ERROR;  
      }
   }
   else
   {
      err_process(1);
      TDKMODE_LOG("set time_wander ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组检测周期
  * 
  *@param[in]   wander_cycle_ms:徘徊检测周期，该值不大于5S
  *@param[in]   near_cycle_ms:接近感应检测周期，该值不大于2S
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_cycle(uint16_t wander_cycle_ms,uint16_t near_cycle_ms)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_wander_cycle_ms = 0;
   uint16_t r_near_cycle_ms = 0;
   if((wander_cycle_ms <= 5000)&&(near_cycle_ms<=2000))
   {
      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}
      tdkmodel_config_Wirtedata_t.cycle_detection_wander = wander_cycle_ms;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.cycle_detection_wander>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.cycle_detection_wander&0xff);
      tdkmodel_i2c_write(REGADDR_CYCLE_DETECTION_WANDER_H,w_reg_buff,2); //< 设置徘徊检测周期

      tdkmodel_i2c_read(REGADDR_CYCLE_DETECTION_WANDER_H,r_reg_buff,2);//< 读取模组的徘徊检测周期
      r_wander_cycle_ms = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      
      tdkmodel_config_Wirtedata_t.cycle_detection_near = near_cycle_ms;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.cycle_detection_near>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.cycle_detection_near&0xff);
      tdkmodel_i2c_write(REGADDR_CYCLE_DETECTION_NEAR_H,w_reg_buff,2);  //< 设置接近感应检测周期

     tdkmodel_i2c_read(REGADDR_CYCLE_DETECTION_NEAR_H,r_reg_buff,2);//< 读取模组的接近感应检测周期 
      r_near_cycle_ms = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
      if((r_wander_cycle_ms ==  tdkmodel_config_Wirtedata_t.cycle_detection_wander)&&(r_near_cycle_ms== tdkmodel_config_Wirtedata_t.cycle_detection_near))
      {
       tdkmodel_config_data_t.cycle_detection_wander = r_wander_cycle_ms;
       tdkmodel_config_data_t.cycle_detection_near = r_near_cycle_ms;
       err_process(0);
       TDKMODE_LOG("set cycle SUCCESS");
       return SUCCESS;
       
      }else 
      {
        err_process(1);
        TDKMODE_LOG("set cycle ERROR");
        return ERROR;  
      }
   }
   else
   {
      err_process(1);
      TDKMODE_LOG("set cycle ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组触发次数
  * 
  *@param[in]   wander_trigger_frequency:徘徊检测触发次数，该值设置不大于100
  *@param[in]   near_trigger_frequency:接近感应触发次数，该值设置不大于100
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_trigger_frequency(uint16_t wander_trigger_frequency,uint16_t near_trigger_frequency)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_wander_trigger_frequency = 0;
   uint16_t r_near_trigger_frequency = 0;
   if((wander_trigger_frequency <= 100)&&(near_trigger_frequency<=100))
   {
      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}
      tdkmodel_config_Wirtedata_t.trigger_frequency_wander = wander_trigger_frequency;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.trigger_frequency_wander);
      tdkmodel_i2c_write(REGADDR_TRIGGER_FREQUENCY_WANDER,w_reg_buff,1);//< 设置徘徊检测触发次数
      
      tdkmodel_config_Wirtedata_t.trigger_frequency_near = near_trigger_frequency;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.trigger_frequency_near);
      tdkmodel_i2c_write(REGADDR_TRIGGER_FREQUENCY_NEAR,w_reg_buff,1);//< 设置接近感应触发次数

      tdkmodel_i2c_read(REGADDR_TRIGGER_FREQUENCY_WANDER,r_reg_buff,1);//< 读取模组的徘徊检测触发次数
      r_wander_trigger_frequency = r_reg_buff[0];

      tdkmodel_i2c_read(REGADDR_TRIGGER_FREQUENCY_NEAR,r_reg_buff,1);//< 读取模组的接近感应触发次数
      if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
    
      r_near_trigger_frequency = r_reg_buff[0];
      if((r_wander_trigger_frequency ==  tdkmodel_config_Wirtedata_t.trigger_frequency_wander)&&(r_near_trigger_frequency== tdkmodel_config_Wirtedata_t.trigger_frequency_near))
      {
       tdkmodel_config_data_t.cycle_detection_wander = r_wander_trigger_frequency;
       tdkmodel_config_data_t.cycle_detection_near = r_near_trigger_frequency;
       TDKMODE_LOG("set trigger_frequency SUCCESS");
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set trigger_frequency ERROR");
        return ERROR;  
      }
   }
   else
   {
      TDKMODE_LOG("set trigger_frequency ERROR");
      return ERROR;
   }

}

/**
  *@brief       设置模组接近感应停留时间
  * 
  *@param[in]   stay_time_ms:接近感应停留时间，该值设置不大于10S
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t set_tdkmodel_time_stay_near(uint16_t stay_time_ms)
{
   uint8_t w_reg_buff[3];
   uint8_t r_reg_buff[3];
   uint16_t r_stay_time_ms = 0;
   if(stay_time_ms <= 10000)
   {
      if(flag == 1) {Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);Device_DelayMs(2);}
      tdkmodel_config_Wirtedata_t.time_stay_near = stay_time_ms;
      w_reg_buff[0] = (uint8_t)(tdkmodel_config_Wirtedata_t.time_stay_near>>8);
      w_reg_buff[1] = (uint8_t)(tdkmodel_config_Wirtedata_t.time_stay_near&0xff);
      tdkmodel_i2c_write(REGADDR_TIME_STAY_NEAR_H,w_reg_buff,2);//< 设置接近感应停留时间
      
      tdkmodel_i2c_read(REGADDR_TIME_STAY_NEAR_H,r_reg_buff,2);//< 读取模组的接近感应停留时间
       if(flag == 1) Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);
    
      r_stay_time_ms = ((uint16_t)r_reg_buff[0])<<8|r_reg_buff[1];
      if(r_stay_time_ms ==  tdkmodel_config_Wirtedata_t.time_stay_near)
      {
       tdkmodel_config_data_t.time_stay_near = r_stay_time_ms;
       TDKMODE_LOG("set near_stay_time_ms SUCCESS");
       return SUCCESS;
       
      }else 
      {
        TDKMODE_LOG("set near_stay_time_ms ERROR");
        return ERROR;  
      }
   }
   else
   {
      TDKMODE_LOG("set near_stay_time_ms ERROR");
      return ERROR;
   }

}

/**
  *@brief       测试TDK模组的注册数据读写
  * 
  *@return      1：无效
  */
static uint32_t tdkmodel_test_regdata(void)
{
    uint8_t wirte_reg_buff[50]={0xE2,0x00,0x01,0x03,0xE8,0x03,0xE8,0x09,0xC4,0x27,0x10,0x03,0xE8,0x03,0xE8,0x03,0xE8,0x03,0xE8,0x00,0x00};
    uint8_t read_reg_buff[50]={0};
    uint8_t i;
    uint8_t tat;
   
    Device_Write(VHW_IRQ_TDKMODEL, NULL, 0, PIN_MODE_S_DRIVE); 
    Device_Write(VHW_IRQ_TDKMODEL, 0, 0, 1); //唤醒
    Device_DelayMs(2);
    tat = tdkmodel_i2c_write(0x00,wirte_reg_buff,20);
    
    for(i=0;i<20;i++)
    {
       
        tat = tdkmodel_i2c_read(i,read_reg_buff,1);
    }
    Device_Write(VHW_IRQ_TDKMODEL, 0, 0, 0); //唤醒
    return 1;
}

/**
  *@brief       传感器使能控制
  * 
  *@param[in]   ctrl:DISABLE：禁能 其他使能
  * 
  *@return      SUCCESS：成功
  */
static ErrorStatus tdksensor_power_ctrl(FunctionalState ctrl) 
{

  if (ctrl == DISABLE) //< 关闭传感器
  {
    Device_Write(VHW_PIN_TDKMODEL_POWER, 0, 0, 1); //< 关闭电源
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);    //< 唤醒脚拉高
    InputPort_DisableProt("DSENSOR_INT");          //< 禁能中断
	Device_Disable(VHW_IIC_TDKMODE);               //< 失能IIC
    TDKMODE_LOG("dsensor power off\r\n");
  } else 
  {
    
      Device_Enable(VHW_IIC_TDKMODE);                //< 使能IIC
      Device_Write(VHW_PIN_TDKMODEL_POWER, 0, 0, 0); //< 打开电源
      Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);    //< 唤醒脚拉低
	  InputPort_EnableProt("DSENSOR_INT");           //< 使能中断
      TDKMODE_LOG("dsensor power on\r\n");
  }
  return SUCCESS;
}

/**
  *@brief       设置传感器接近感应灵敏度
  * 
  *@param[in]   val:传感器灵敏度，分为高、中、低、关闭
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static ErrorStatus dsensor_set_sensitivity(Dsensor_Sensitivity_enum_t val) 
{
  int distance_near,threshold_near;
  tdkwander_info.threshold_near = val;
  OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//< 保存参数
  if (val == DSENSOR_SENS_H )//< 高灵敏度
  {
    TDKMODE_LOG("接近高灵敏度\r\n");
    distance_near = 1000;//< 距离
    threshold_near = 500;//< 强度
    set_tdkmodel_distance_near(distance_near);
     return set_tdkmodel_threshold_near(threshold_near);//< 接近感应强度阈值
  } 
  else if (val == DSENSOR_SENS_M )//< 中灵敏度
  {
    TDKMODE_LOG("接近中灵敏度\r\n");
    distance_near = 700;
    threshold_near = 1000;
    set_tdkmodel_distance_near(distance_near);
    return set_tdkmodel_threshold_near(threshold_near);//< 接近感应强度阈值
  } 
  else if (val == DSENSOR_SENS_L )//< 低灵敏度
  {
    TDKMODE_LOG("接近低灵敏度\r\n");
    distance_near = 400;
    threshold_near = 1500;
    set_tdkmodel_distance_near(distance_near);
   return set_tdkmodel_threshold_near(threshold_near);//< 接近感应强度阈值
  }else if (val == DSENSOR_SENS_OFF)//< 传感器关闭
  {
    TDKMODE_LOG("接近关闭\r\n");
    tdkwander_info.near_enable = DISABLE;
    OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//保存参数
    return set_tdkmodel_swich_near(0);
  }
  return ERROR;
}

/**
  *@brief       获取传感器灵敏度
  * 
  * 
  *@return      tdkwander_info.threshold_near:传感器灵敏度，分为高、中、低、关闭
  */
static Dsensor_Sensitivity_enum_t dsensor_get_sensitivity(void)
{
  return tdkwander_info.threshold_near;
}

/**
  *@brief       设置徘徊感器灵敏度
  * 
  *@param[in]   level：灵敏度等级,分为高、中、低
  * 
  *@return      SUCCESS：成功
  */
static uint32_t Pir_SetSentivity(TDKsensor_Sensitivity_enum_t level) 
{
  uint16_t distance_wander;
  uint8_t threshold_wander;
  //< 设置徘徊传感器灵敏度主要设置感应距离和触发阈值
  tdkwander_info.threshold_wander = level;
  OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//< 保存参数
  if (level == TDKSENSOR_SENS_H )//< 高灵敏度
  {
    TDKMODE_LOG("徘徊高灵敏度\r\n");
    distance_wander = 2200;//
    threshold_wander = 2;
    set_tdkmodel_distance_wander(distance_wander);//设置徘徊距离
    set_tdkmodel_threshold_wander(threshold_wander);//徘徊强度阈值
  } 
  else if (level == TDKSENSOR_SENS_M )//中灵敏度
  {
    TDKMODE_LOG("徘徊中灵敏度\r\n");
    distance_wander = 1700;
    threshold_wander = 1;
    set_tdkmodel_distance_wander(distance_wander);//设置徘徊距离
    set_tdkmodel_threshold_wander(threshold_wander);//徘徊强度阈值
  } 
  else if (level == TDKSENSOR_SENS_L )//低灵敏度
  {
    TDKMODE_LOG("徘徊低灵敏度\r\n");
    distance_wander = 1200;
    threshold_wander = 0;
    set_tdkmodel_distance_wander(distance_wander);//设置徘徊距离
    set_tdkmodel_threshold_wander(threshold_wander);//徘徊强度阈值
  }
  tdk_timeout_timestamp = 0;
  return SUCCESS;
}

/**
  *@brief       设置TDK模组徘徊时间
  * 
  *@param[in]   level：徘徊时间
  * 
  *@return      0:无效
  */
static uint32_t Pir_SetWanderTime(uint32_t time)
{
    tdkwander_info.wander_time = time;
    switch (tdkwander_info.wander_time)
    {
    case 10000:
       set_tdkmodel_stay_time_wander(10000);
        break;

    case 20000:
       set_tdkmodel_stay_time_wander(20000);
        break;

    case 30000:
        set_tdkmodel_stay_time_wander(30000);
        break;

    case 60000:
        set_tdkmodel_stay_time_wander(60000);
        break;
    
    default:
        return 0;
    }
    tdk_timeout_timestamp = 0;
    OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));

    return 0;
}

/**
  *@brief       获取徘徊传感器灵敏度
  * 
  * 
  *@return      tdkwander_info.threshold_wande:传感器灵敏度，分为高、中、低
  */
static Dsensor_Sensitivity_enum_t dsensor_get_sensitivity_wander(void)
{
  return tdkwander_info.threshold_wander;
}

/**
  *@brief       TDK传感器中断处理回调函数
  *@details     只创建中断事件，任务里面处理
  * 
  *@param[in]   name：按键的名字，如该组件中，配置中断中的"DSENSOR_INT"
  *@param[in]   status：触发的状态，按下，松开，长按等状态
  *@param[in]   times：次数，单击就是0，双击就是1，三击就是2
  * 
  *@return      NULL
  */
static void dsensor_irqHandle(char *name, uint8_t status, uint8_t times)
{
   
    if (status == INPUT_PORT_STA_PRESS)
    {  
        OSAL_EventCreateFromISR(COMP_DSENSOR);    
    }
}

/**
  *@brief       读传感器触发标志
  * 
  *@return      SUCCESS：触发   ERROR：未触发
  */
static uint32_t tdkmodel_read_triggerdata(void)
{
   
    uint8_t reg_buff[5];
    uint8_t i;
    if(tdkmodel_config_data_t.trigger_flag !=0)
    {   
        tdkmodel_read_regdata(); //< 传感器读寄存器所有数据
        TDKMODE_LOG("wander_enable =%x",tdkwander_info.wander_enable);
        if(tdkwander_info.wander_state == 1)
        {
            if((tdkmodel_config_data_t.trigger_flag&0x01)==1)//徘徊触发
            { 
                TDKMODE_LOG("linger trigger,distance =%d",tdkmodel_config_data_t.realtrigger_distance_wander);
                dsensor_msg.type = WANDER_TRIG;//消息类型 徘徊触发
                dsensor_msg.wander_msg.alarm = 1;
                OSAL_MessagePublish(&dsensor_msg, sizeof(DsensorMsg_t));//上报徘徊消息
                OSAL_TimeGet(&tdk_timeout_timestamp, T_UTC);//清除5分钟计数 
                tdkwander_info.wander_state =0;//5分钟內不响应徘徊
            } 
        }  

        if((tdkmodel_config_data_t.trigger_flag&0x02)==0x02)//接近感应触发
        {
            dsensor_msg.type = READ_DISTANCE;//消息类型 读距离
            dsensor_msg.ps_msg.action = USER_ACTION_PRESS;//操作被触发
            dsensor_msg.ps_msg.distance = tdkmodel_config_data_t.realtrigger_distance_near;//触发距离
            dsensor_msg.ps_msg.cfi = tdkmodel_config_data_t.strength_trigger_threshold_near;
            TDKMODE_LOG("Proximity trigger,distance =%d",tdkmodel_config_data_t.realtrigger_distance_near);
		    OSAL_MessagePublish(&dsensor_msg, sizeof(DsensorMsg_t));
        }
       
        return SUCCESS;
    }else
    {
        return ERROR;
    }
}

/**
  *@brief       确认是否为徘徊触发
  * 
  *@return      SUCCESS：触发   ERROR：未触发
  */
static uint32_t TDKmodel_Read_Wanderdata(void)
{
    uint8_t  state;
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 1);        //< 唤醒脚拉高
    Device_DelayMs(2);
    tdkmodel_i2c_read(REGADDR_TRIGGER_FLAG,&state,1);   //< 传感器触发标志
    Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0);        //< 唤醒脚拉高
    if((state&0x01)==1)  //徘徊触发
    {
        TDKMODE_LOG("徘徊报警触发！！");
        dsensor_msg.type = WANDER_TRIG;//消息类型 徘徊触发
        dsensor_msg.wander_msg.alarm = 1;
        OSAL_MessagePublish(&dsensor_msg, sizeof(DsensorMsg_t));//上报徘徊消息
        OSAL_TimeGet(&tdk_timeout_timestamp, T_UTC);//清除5分钟计数 
        tdkwander_info.wander_state =0;//5分钟內不响应徘徊
        return SUCCESS;
    }
    return ERROR;
}

/**
  * @brief  传感器进入测试模式
  * @note
  * @return SUCCESS/ERROR
  */
/**
  *@brief       传感器进入测试模式
  * 
  *@param[in]   mode：设置的模式 
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static ErrorStatus dsensor_set_demo_mode(uint8_t mode)
{
	demo_mode = mode;
    TDKMODE_LOG( "dsensor test open\r\n" );
    return SUCCESS;
}

/**
  *@brief       唤醒逻辑处理
  * 
  *@param[in]   device：虚拟设备 
  * 
  *@return      SUCCESS：成功   ERROR：失败
  */
static uint32_t Dsensor_WakeupHandle(uint32_t device)
{
    if (device == VHW_IRQ_TDKMODEL)   //< 中断唤醒处理
    { 
        Device_Enable(VHW_IIC_TDKMODE);//使能IIC
        if(tdkmodel_read_triggerflag()==SUCCESS)
        {
        TDKMODE_LOG("work_state=%d",tdkmodel_config_data_t.work_state);
        Device_Disable(VHW_IIC_TDKMODE);//失能IIC
        if(((tdkmodel_config_data_t.trigger_flag&0x01)==1 && tdkwander_info.wander_state == 1)\ 
                || ((tdkmodel_config_data_t.trigger_flag&0x02)==0x02)) //徘徊触发
        {
            TDKMODE_LOG("Dsensor_WakeupHandle! wander_state =%d",tdkwander_info.wander_state);
            OSAL_EventSingleCreate(COMP_DSENSOR, EVENT_GET_WANDER, 10, EVT_PRIORITY_LOW); //< 检测徘徊传感器事件
            return SUCCESS;
        }
        }
    }
   return ERROR;
}
COMPONENT_WAKEUP_EXPORT(COMP_DSENSOR, Dsensor_WakeupHandle, VHW_IRQ_TDKMODEL);
uint8_t powerflag = 1;  //< 锁端上电启动后，模组设置参数执行2次
static uint8_t event_flag = 0;  //< 徘徊检测事件标志，1：已创建；0：未创建或已删除

/**
  *@brief       TDK传感器任务函数
  * 
  *@param[in]   event：当前任务的所有事件 
  * 
  *@return      返回未处理的事件
  */
static uint32_t Dsensor_Task(uint32_t event)
{
    
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{
		TDKMODE_LOG("TDKMODEL DSENSOR START!\r\n");
        InputPort_stu_t port[] = 
		{
			{"DSENSOR_INT", VHW_IRQ_TDKMODEL, INPUT_PORT_LOGIC_HIGH, INPUT_PORT_FUNC_SINGLE}, //配置中断脚
        };
        /* 注册端口 */
        InputPort_Registered(port, OSAL_LENGTH(port), dsensor_irqHandle);
        Device_Enable(VHW_IIC_TDKMODE); //< 使能IIC
        Device_Write(VHW_PIN_TDKMODEL_POWER, 0, 0, 0); //< 打开电源
	    InputPort_EnableProt("DSENSOR_INT");   
        if(powerflag > 0)
        {
            /**  powerflag =2 原因：TDK模组第一次上电启动比较慢，可能造成写入失败或无效，因此多设置1次 **/
            powerflag --;
            OSAL_EventSingleCreate(COMP_DSENSOR, EVENT_SET_PARA, 1500, EVT_PRIORITY_MEDIUM); //< 设置传感器参数
            OSAL_NvRead(0, &tdkwander_info, sizeof(tdkwander_info));
        }
        else if((tdkmodel_config_data_t.work_state&0x01)!=tdkwander_info.wander_enable || \
        (tdkmodel_config_data_t.work_state&0x02)/2 != tdkwander_info.near_enable) 
        {
            OSAL_EventSingleCreate(COMP_DSENSOR, EVENT_SET_PARA, 100, EVT_PRIORITY_MEDIUM); //< 设置传感器参数
        }   
        SYS_API(tdkmodel_set_onoff);       //< TDK传感器功能总开关设置
        SYS_API(dsensor_power_ctrl);     //< 接近感应功能使能接口
        SYS_API(dsensor_set_sensitivity);//< 注册设置灵敏度接口
        SYS_API(dsensor_get_sensitivity);//< 注册获取灵敏度接口
        SYS_API(dsensor_set_demo_mode);  //< 传感器进入测试模式
        SYS_API(tdkmodel_read_softversion);  //< 传感器读版本

        SYS_API(Pir_SetSentivity); //< 注册徘徊灵敏度设置接口
        SYS_API(Pir_SetWanderTime);//< 注册徘徊时间设置接口
        SYS_API(Pir_Switch);       //< 注册徘徊开关控制接口
		return (event ^ EVENT_SYS_START);
	}

	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        InputPort_DisableProt("DSENSOR_INT");
        Device_Disable(VHW_IIC_TDKMODE);            //< 失能IIC
        Device_Write(VHW_PIN_TDKMODEL_EN, 0, 0, 0); //< 唤醒脚拉低
        TDKMODE_LOG("dsensor sleep\r\n");
        return (event ^ EVENT_SYS_SLEEP);
	}
    /* 上电的时候设置传感器参数 */
	if (event & EVENT_SET_PARA)
	{
      TDKMODE_LOG("tdkwander demo mode:%d",demo_mode);
      TDKMODE_LOG("tdkwander_info.init_flag =%x",tdkwander_info.init_flag);
      TDKMODE_LOG("tdkwander_info.wander_enable =%d",tdkwander_info.wander_enable);
      TDKMODE_LOG("tdkwander_info.threshold_wander =%d",tdkwander_info.threshold_wander);
      TDKMODE_LOG("tdkwander_info.wander_time =%d",tdkwander_info.wander_time);
      TDKMODE_LOG("tdkwander_info.near_enable =%d",tdkwander_info.near_enable);
      TDKMODE_LOG("tdkwander_info.threshold_near =%d",tdkwander_info.threshold_near);
     if(tdkwander_info.init_flag != 0xFA)//< 没有初始数据
     {
       tdkwander_info.wander_state = 0;//初始化为0
       TDKDevice_Enable();
       tdkwander_info.init_flag = 0xFA;
       Pir_SetSentivity(TDKSENSOR_SENS_M);//< 默认徘徊灵敏度中
       Pir_SetWanderTime(10000);//< 默认徘徊时间10s

       dsensor_set_sensitivity(DSENSOR_SENS_H);//< 默认接近感应灵敏度高
       set_tdkmodel_trigger_frequency(3,2);//设置模组触发次数
       set_tdkmodel_time_stay_near(100);//接近感应停留时间
       set_tdkmodel_cycle(100,100);//设置检测周期
       TDKDevice_DisEnable();    
       OSAL_NvWrite(0, &tdkwander_info, sizeof(tdkwander_info));//< 写入配置 
     }
     else
     {
        /*** 已有初始化数据 **/
        tdkwander_info.init_flag = 0xFA;
        TDKDevice_Enable();     
        Pir_SetSentivity(tdkwander_info.threshold_wander);//< 设置徘徊灵敏度
        Pir_SetWanderTime(tdkwander_info.wander_time);//< 设置徘徊时间
        
        dsensor_set_sensitivity(tdkwander_info.threshold_near);//< 设置接近感应灵敏度
        /** 徘徊功能使能设置 **/  
        set_tdkmodel_swich_wander(tdkwander_info.wander_enable);
        /** 接近感应使能设置 */
        set_tdkmodel_swich_near(tdkwander_info.near_enable);
        set_tdkmodel_trigger_frequency(3,2);//设置模组触发次数
        set_tdkmodel_time_stay_near(100);//接近感应停留时间
        set_tdkmodel_cycle(100,100);//设置检测周期
        TDKDevice_DisEnable();
     }
  
		return (event ^ EVENT_SET_PARA);
	}
    /* 系统中断事件 */
	if (event & EVENT_SYS_ISR)
	{
        if(demo_mode == 1)
        {
            uint16_t ps;
            uint16_t cfi;
            tdkmodel_read_testdata(&ps, &cfi);

            dsensor_msg.type = READ_DISTANCE;
            dsensor_msg.ps_msg.distance = ps;
            dsensor_msg.ps_msg.cfi = cfi;
            dsensor_msg.ps_msg.action = USER_ACTION_INVALID;
		    OSAL_MessagePublish(&dsensor_msg, sizeof(DsensorMsg_t));
            return (event ^ EVENT_SYS_ISR);
        }
        if(event_flag == 1 && TDKmodel_Read_Wanderdata() == SUCCESS)
        {
            //< 检测到徘徊触发，并上报了应用层，关闭该任务
            event_flag = 0;
            TDKMODE_LOG("Delete wander trigger of detection event!\r\n");
        }
        return (event ^ EVENT_SYS_ISR);
    }

    /* 系统唤醒后，检测接近徘徊事件 */
	if (event & EVENT_GET_WANDER)
	{
        if(demo_mode == 1) {return (event ^ EVENT_GET_WANDER);} //< 如果进入测试模式，则中断模式直接退出

        /*** 执行中断处理逻辑 **/
        TDKMODE_LOG("wander_enable=%d",tdkwander_info.wander_enable);
        TDKMODE_LOG("tdk_timeout_timestamp=%d",tdk_timeout_timestamp);
        tdkmodel_read_triggerdata();//读传感器数据
        if(tdkwander_info.wander_enable == 1)//只是接近触发，还要检测是否有徘徊
        {
            /** 开启检测徘徊时间 ***/
            if(tdkmodel_config_data_t.trigger_flag == 0x03 && event_flag == 1)
            {
                event_flag = 0;
            }
            else if(tdkmodel_config_data_t.trigger_flag == 0x02 && tdkwander_info.wander_state == 1)
            {
                if(event_flag == 0) event_flag = 1;
            }
        }
        return (event ^ EVENT_GET_WANDER);
	}

	return 0;
}
COMPONENT_TASK_EXPORT(COMP_DSENSOR, Dsensor_Task, sizeof(tdkwander_info));

/**
  *@brief       低功耗定时器回调函数
  *@details     该定时回调函数每300ms会调用一次，用于累计时间，当时间超过5分钟会检测一次徘徊传感器状态
  *  
  *@param[in]   dev: 虚拟设备
  * 
  *@return      ret：无用的参数
  */
static uint32_t Tdk_TimedWakeupHandle(uint32_t dev)
{
    uint32_t ret = 0;
    uint32_t cur_rtc = 0;
    OSAL_TimeGet(&cur_rtc, T_UTC);

    if((tdkwander_info.wander_enable) && ((cur_rtc-tdk_timeout_timestamp) >= TDK_TIMEOUT_TIME) )   //< 满足5分钟，才会再次检测
    {
      tdkwander_info.wander_state = 1;
    }
    return ret;
}
COMPONENT_WAKEUP_EXPORT(COMP_DSENSOR, Tdk_TimedWakeupHandle, vTIMER_1); 




